/*
 * @Author: xiaosihan 
 * @Date: 2023-08-16 01:17:45 
 * @Last Modified by: xiaosihan
 * @Last Modified time: 2024-10-20 07:38:07
 */


import { ZoomInOutlined, ZoomOutOutlined } from "@ant-design/icons";
import designEditor from "@/editorComponent/designEditor";
import editorStore from "@/editorComponent/editorStore";
import textureManager from "@/editorComponent/textureManager";
import { Button, Dropdown, Popconfirm, Slider, Tooltip } from "antd";
import clsx from "clsx";
import { cloneDeep, get, set } from "lodash";
import { autorun } from "mobx";
import { useEffect, useRef, useState } from "react";
import copySVG from "./copy.svg?raw";
import copyToSVG from "./copyTo.svg?raw";
import delSVG from "./del.svg?raw";
import layeroutSVG from "./layerout.svg?raw";
import lockSVG from "./lock.svg?raw";
import styles from "./toolMenu.module.less";
import unlockSVG from "./unlock.svg?raw";
import { fabric } from "fabric";

interface Iprops {
}

// 菜单工具条
export default function ToolMenu() {

  const dom = useRef<HTMLDivElement | null>(null);
  const [data, setData] = useState({});
  const [visible, setVisible] = useState(false);
  const [hoverBtn, setHoverBtn] = useState<"" | "up" | "down">("");
  const [maxLayerout, setMaxLayerput] = useState(0);
  const [currentLayerout, setCurrentLayerout] = useState(0);
  const [lock, setLock] = useState(false);
  const [showCopyTo, setShowCopyTo] = useState(false);
  const [disable, setDisable] = useState(false);

  const [componentList, setComponentList] = useState<Array<{ key: string, name: string }>>([]);

  const [activeComponent, setActiveComponent] = useState(editorStore.activeComponent);

  useEffect(() => autorun(() => {
    const goodsData = editorStore.goodsData;
    if (goodsData) {
      const componentList = goodsData.component.filter(c => c.enable === true).map(c => {
        return {
          key: c.key,
          name: c.name
        }
      })
      setComponentList(componentList);
    }
  }, { delay: 10 }), []);

  useEffect(() => autorun(() => {
    setActiveComponent(editorStore.activeComponent);
  }), []);

  useEffect(() => autorun(() => {
    setLock(editorStore.lock);
  }), []);

  useEffect(() => autorun(() => {
    const { activeObjectId, lock } = editorStore;
    setDisable(lock);
    const activeObject = designEditor.fabricCanvas.getActiveObject();
    if (activeObjectId && activeObject && !["name", "num"].includes(activeObject.name || "")) {
      setVisible(true);
    } else {
      setVisible(false);
    }
  }), []);

  // 更新层级
  const updataLayerout = () => {
    const objects = designEditor.fabricCanvas.getObjects();
    setMaxLayerput(objects.length - 1);

    const activeObject = designEditor.fabricCanvas.getActiveObject();
    if (activeObject) {
      const layerout = objects.indexOf(activeObject);
      setCurrentLayerout(layerout);
    }
  }

  //上移一层
  const upMovellayerout = () => {
    const activeObject = designEditor.fabricCanvas.getActiveObject();
    if (activeObject) {
      setCurrentLayerout(currentLayerout + 1);
      activeObject.moveTo(Math.min(maxLayerout, currentLayerout + 1));
    }
  }

  //下移一层
  const downMovellayerout = () => {
    const activeObject = designEditor.fabricCanvas.getActiveObject();
    if (activeObject) {
      setCurrentLayerout(currentLayerout - 1);
      activeObject.moveTo(Math.max(0, currentLayerout - 1));
    }
  }

  //复制对象到其他面
  const copyToOtherSide = async (keys: Array<string>) => {
    setShowCopyTo(false);
    const { activeObjectId } = editorStore;
    const activeObjects = designEditor.fabricCanvas.getActiveObjects();
    designEditor.fabricCanvas.discardActiveObject();
    const objDatas = activeObjects.map(o => o.toJSON(["id", "name", "repeat", "repeatSpaceX", "repeatSpaceY", "lockMovementX", "lockMovementY", "lockRotation", "lockScalingX", "lockScalingY", "lockSkewingX", "lockSkewingY"]) as unknown as fabric.Object);
    if (activeObjects.length > 1) {
      //@ts-ignore
      const activeObject = new fabric.ActiveSelection(activeObjects, { canvas: designEditor.fabricCanvas });
      designEditor.fabricCanvas.setActiveObject(activeObject);
    } else {
      designEditor.fabricCanvas.setActiveObject(activeObjects[0]);
    }
    designEditor.render();

    if (activeObjectId && activeObjects) {
      for (let key of keys) {
        const objDatas_clone = cloneDeep(objDatas);
        const objects = get(editorStore.design_data, ["designData", key, "objects"]) || [];
        const fabricMark = designEditor.fabricMarkMap.get(key);
        const currentFabricMark = designEditor.fabricMarkMap.get(editorStore.activeComponent);
        if (fabricMark && currentFabricMark) {
          const keepScale = fabricMark.scaleX! / currentFabricMark.scaleX!;
          objDatas_clone.map(o => o.scaleX! *= keepScale);
          objDatas_clone.map(o => o.scaleY! *= keepScale);
        }
        objects.push(...objDatas_clone);
        set(editorStore.design_data, ["designData", key, "objects"], objects);
        set(editorStore.design_data, ["designData", key, "version"], "5.3.0");
        const fabricJson = get(editorStore.design_data, ["designData", key]) || {};
        await textureManager.updataTextByFabricJSON(key, fabricJson);
        const textCanvasCtx = textureManager.getContext(key);

        if (fabricMark && textCanvasCtx) {
          fabricMark.clip(textCanvasCtx, 1024, 1);
        }
        //绘制背景颜色
        if (textCanvasCtx) {
          textCanvasCtx.save();
          textCanvasCtx.fillStyle = fabricJson.background || "#ffffff";
          textCanvasCtx.globalCompositeOperation = "destination-over";
          textCanvasCtx.fillRect(0, 0, 1024, 1024);
          textCanvasCtx.restore();
        }

        editorStore.modifyDesignData(fabricJson, key);
      }
    }

  }

  return (
    <div className={clsx(styles.toolMenu, visible && styles.visible)} >
      {/* 放大 */}
      <Tooltip
        title="放大(alt+=)"
        placement="bottom"
        mouseLeaveDelay={0}
        mouseEnterDelay={0.5}
      >
        <span
          className={clsx(styles.btn, disable && styles.disable)}
          onClick={() => {
            designEditor.amplify();
          }}
        >
          <ZoomInOutlined />
        </span>
      </Tooltip>
      {/* 缩小 */}
      <Tooltip
        title="缩小(alt+-)"
        placement="bottom"
        mouseLeaveDelay={0}
        mouseEnterDelay={0.5}
      >
        <span
          className={clsx(styles.btn, disable && styles.disable)}
          onClick={() => {
            designEditor.reduce();
          }}
        >
          <ZoomOutOutlined />
        </span>
      </Tooltip>

      {/* 调整层级 */}
      <Tooltip
        title="图层"
        placement="bottom"
        mouseLeaveDelay={0}
        mouseEnterDelay={0.5}
      >
        <Dropdown
          trigger={["click"]}
          placement="top"
          destroyPopupOnHide={true}
          onOpenChange={open => {
            if (open) {
              updataLayerout();
            }
          }}
          dropdownRender={menus => {
            return (
              <div className={styles.move_layerout} >
                <span className={styles.layerout_sort} >图层顺序</span>
                <Button
                  block
                  disabled={maxLayerout === currentLayerout}
                  type={hoverBtn === "up" ? "primary" : undefined}
                  onMouseEnter={() => setHoverBtn("up")}
                  onMouseLeave={() => setHoverBtn("")}
                  onClick={() => upMovellayerout()}
                >上移</Button>
                <Slider
                  vertical
                  min={0}
                  max={maxLayerout}
                  step={1}
                  value={currentLayerout}
                  onChange={layerout => {
                    setCurrentLayerout(layerout);
                    const activeObject = designEditor.fabricCanvas.getActiveObject();
                    if (activeObject) {
                      activeObject.moveTo(layerout);
                    }
                  }}
                  style={{ height: 150, margin: "10px auto" }}
                />
                <Button
                  block
                  disabled={0 === currentLayerout}
                  type={hoverBtn === "down" ? "primary" : undefined}
                  onMouseEnter={() => setHoverBtn("down")}
                  onMouseLeave={() => setHoverBtn("")}
                  onClick={() => downMovellayerout()}
                >下移</Button>
              </div>
            )
          }}
        >
          <span
            className={clsx(styles.btn, disable && styles.disable)}
            dangerouslySetInnerHTML={{ __html: layeroutSVG }}
          >
          </span>
        </Dropdown>

      </Tooltip>

      {/* 复制 */}
      <Tooltip
        title="复制(ctrl+D)"
        placement="bottom"
        mouseLeaveDelay={0}
        mouseEnterDelay={0.5}
      >
        <span
          className={clsx(styles.btn, disable && styles.disable)}
          dangerouslySetInnerHTML={{ __html: copySVG }}
          onClick={() => {
            designEditor.copy();
          }}
        >
        </span>
      </Tooltip>

      {/* 复制到其他部位 */}
      <Tooltip
        title="复制到其他印刷面"
        placement="bottom"
        mouseLeaveDelay={0}
        mouseEnterDelay={0.5}
      >
        <Dropdown
          trigger={["click"]}
          placement="top"
          open={showCopyTo}
          onOpenChange={open => setShowCopyTo(open)}
          destroyPopupOnHide={true}
          arrow
          dropdownRender={menus => {
            return (
              <div className={styles.copy_to}>
                <Button
                  block
                  className={styles.copy_to_item}
                  onClick={() => {
                    const componets = componentList
                      .filter(c => c.key !== activeComponent)
                      .map((c, i) => {
                        return c.key;
                      })
                    copyToOtherSide(componets);
                  }}
                >所有面</Button>
                {
                  componentList
                    .filter(c => c.key !== activeComponent)
                    .map((c, i) => {
                      return (
                        <Button
                          key={i}
                          block
                          className={styles.copy_to_item}
                          onClick={() => {
                            copyToOtherSide([c.key]);
                          }}
                        >{c.name}</Button>
                      )
                    })
                }
              </div>
            )
          }}
        >
          <span
            className={clsx(styles.btn, disable && styles.disable)}
            dangerouslySetInnerHTML={{ __html: copyToSVG }}
          >
          </span>
        </Dropdown>
      </Tooltip>

      {/* 锁 */}
      <Tooltip
        title="锁"
        placement="bottom"
        mouseLeaveDelay={0}
        mouseEnterDelay={0.5}
      >
        <span
          className={clsx(styles.btn, lock && styles.red)}
          dangerouslySetInnerHTML={{ __html: lock ? lockSVG : unlockSVG }}
          onClick={() => {
            designEditor.setLockState(!lock);
            setLock(!lock);
          }}
        >
        </span>
      </Tooltip>

      {/* 删除 */}
      <Tooltip
        title="删除(del)"
        placement="bottom"
        mouseLeaveDelay={0}
        mouseEnterDelay={0.5}
      >
        <Popconfirm
          title="确定要删除当前组?"
          okText="确定"
          cancelText="取消"
          onConfirm={() => {
            designEditor.delActiveObject();
          }}
        >
          <span
            className={clsx(styles.btn, disable && styles.disable)}
            dangerouslySetInnerHTML={{ __html: delSVG }}
          >
          </span>
        </Popconfirm>
      </Tooltip>

    </div >
  );

}